import React, { useEffect, useRef } from 'react';
import { useSelector } from 'react-redux';

import { State, Message } from '../../state/reducer';
import useIsLogin from '../../hooks/useIsLogin';
import useAction from '../../hooks/useAction';
import { getLinkmanHistoryMessages, getDefaultGroupHistoryMessages } from '../../service';
import MessageComponent from './Message/Message';

import Style from './MessageList.less';
import { IChatPostMessageArgs } from '../../types/postMessage';
import { ChatPostMessageTypeEnum } from '../../enums/postMessage';

function MessageList() {
    const action = useAction();
    const selfId = useSelector((state: State) => state.user?._id);
    const focus = useSelector((state: State) => state.focus);
    const isGroup = useSelector((state: State) => state.linkmans[focus].type === 'group');
    const creator = useSelector((state: State) => state.linkmans[focus].creator);
    const messages = useSelector((state: State) => state.linkmans[focus].messages);
    const isLogin = useIsLogin();
    const tagColorMode = useSelector((state: State) => state.status.tagColorMode);

    const $list = useRef(null);

    useEffect(() => {
        const handler = (event: MessageEvent) => {
            const { data } = event;
            const postData = data as IChatPostMessageArgs;
            if (postData) {
                switch (postData.type) {
                    case ChatPostMessageTypeEnum.CHAT_SEND_SCREENSHOT: {
                        break;
                    }
                    case ChatPostMessageTypeEnum.CHAT_SEND_PASTE: {
                        break;
                    }
                    case ChatPostMessageTypeEnum.CHAT_GET_CODE: {
                        /** 倒找消息列表，找到第一个符合的 */
                        const msgArr = Object.values(messages);
                        const { length } = msgArr;
                        let content = '';
                        for (let index = length - 1; index >= 0; index--) {
                            if (msgArr[index].type === 'code') {
                                content = msgArr[index].content;
                                /** 正则去代码 */
                                content = content.replace(/@\S+?@/, '');
                                // 代码复制到剪切板
                                /** 具体思路
                                 * 1.创建一个input元素
                                 * 2.设置元素的值
                                 * 3.选中该元素
                                 * 4.执行copy操作
                                 * */
                                const copy = (value: string) => {
                                    const transfer = document.createElement('textarea');
                                    document.body.appendChild(transfer);
                                    transfer.value = value; // 这里表示想要复制的内容
                                    transfer.focus();
                                    transfer.select();
                                    if (document.execCommand('copy')) {
                                        document.execCommand('copy');
                                    }
                                    transfer.blur();
                                    console.log('复制成功');
                                    document.body.removeChild(transfer);
                                };
                                copy(content);
                                break;
                            }
                        }
                        console.log('content', content);
                        break;
                    }
                    default:
                        break;
                }
            }
        };
        window.addEventListener('message', handler);

        return () => {
            /** 解绑消息监听 */
            window.removeEventListener('message', handler);
        };
    }, [focus, messages]);

    let isFetching = false;
    async function handleScroll(e: any) {
        // Don't know why the code-view dialog will also trigger when scrolling
        if ($list.current && e.target !== $list.current) {
            return;
        }
        if (isFetching) {
            return;
        }

        const $div = e.target;
        if ($div.scrollTop === 0 && $div.scrollHeight > $div.clientHeight) {
            isFetching = true;
            let historyMessages: Message[] = [];
            if (isLogin) {
                historyMessages = await getLinkmanHistoryMessages(
                    focus,
                    Object.keys(messages).length,
                );
            } else {
                historyMessages = await getDefaultGroupHistoryMessages(
                    Object.keys(messages).length,
                );
            }
            if (historyMessages && historyMessages.length > 0) {
                action.addLinkmanHistoryMessages(focus, historyMessages);
            }
            isFetching = false;
        }
    }

    function renderMessage(message: Message) {
        const isSelf = message.from._id === selfId;
        let shouldScroll = true;
        if ($list.current) {
            // @ts-ignore
            const { scrollHeight, clientHeight, scrollTop } = $list.current;
            shouldScroll = isSelf
                || scrollHeight === clientHeight
                || scrollTop === 0
                || scrollTop > scrollHeight - clientHeight * 2;
        }

        let { tag } = message.from;
        if (!tag && isGroup && message.from._id === creator) {
            tag = '群主';
        }

        return (
            <MessageComponent
                key={message._id}
                id={message._id}
                linkmanId={focus}
                isSelf={isSelf}
                userId={message.from._id}
                avatar={message.from.avatar}
                username={message.from.username}
                originUsername={message.from.originUsername}
                time={message.createTime}
                type={message.type}
                content={message.content}
                tag={tag}
                loading={message.loading}
                percent={message.percent}
                shouldScroll={shouldScroll}
                tagColorMode={tagColorMode}
            />
        );
    }

    return (
        <div className={`${Style.messageList} show-scrollbar`} onScroll={handleScroll} ref={$list}>
            {Object.values(messages).map((message) => renderMessage(message))}
        </div>
    );
}

export default MessageList;
